package com.ygqh.baby.controller.admin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.controller.utils.DocumentHandler;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.model.ReturnOrderReportModel;
import com.ygqh.baby.model.ReturnOrderReportReq;
import com.ygqh.baby.model.YgReturnOrderInfoModel;
import com.ygqh.baby.model.wdt.WdtResult;
import com.ygqh.baby.model.wdt.qyb.WdtQybResult;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.alipay.util.AlipayNotify;
import com.ygqh.baby.service.alipay.util.AlipaySubmit;
import com.ygqh.baby.service.task.WdtService;
import com.ygqh.baby.service.wdtqyb.api.WdtQybApi;
import com.ygqh.baby.service.wdtqyb.exception.WdtException;
import com.ygqh.baby.service.wechat.YgWeChatService;
import com.ygqh.baby.shiro.utils.SessionUtil;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ThreadPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Controller
@RequestMapping("/admin/returnorder")
public class ReturnOrderController extends BaseController<Object, java.lang.Long> {

	@Autowired
	private YgReturnOrderService ygReturnOrderService;
	@Autowired
	private YgReturnOrderDetailService ygReturnOrderDetailService;
	@Autowired
	private YgReturnLogService ygReturnLogService;
	@Autowired
	private YgReturnOrderLogService ygReturnOrderLogService;
	@Autowired
	private FileService fileService;
	@Autowired
	private YgOrderService ygOrderService;
	@Autowired
	private YgWeChatService ygWeChatService;
	@Autowired
	private WdtService wdtService;
	@Autowired
	private WdtQybApi wdtQybApi;
	@Autowired
	private YgAlipayRefundRecordService ygAlipayRefundRecordService;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgPrepayBookRecordService ygPrepayBookRecordService;
	@Autowired
	private AlipaySubmit AlipaySubmit;
	@Autowired
	private AlipayNotify AlipayNotify;
	@Autowired
	private YgReturnOrderReportService ygReturnOrderReportService;

	@Autowired
	private ThreadPool threadPool;
	@Value("${alipay.refund.service}")
	private String refundService;
	@Value("${alipay.charset}")
	private String charset;
	@Value("${alipay.gatewayUrl}")
	private String gatewayUrl;
	@Value("${alipay.partner}")
	private String partner;
	@Value("${alipay.seller_id}")
	private String sellerId;
	@Value("${alipay.refund_fastpay_notify_url}")
	private String refundFastpayNotifyUrl;

	@RequestMapping("searchOrder")
	@ResponseBody
	public Map<String, Object> searchOrder(String q, QueryInfo queryInfo, Date startDate, Date endDate, ReturnStatus status, Long orderId, String userName,
			String returnCode, ReturnType returnType, String expressCode, String productName) {

		ResultSet<YgReturnOrder> resultSet = ygReturnOrderService.search(queryInfo, q, userName, returnType, returnCode, startDate, endDate, orderId, status,
				expressCode, productName);

		return resultSet.toDatatables(null);
	}

	@RequestMapping("returnorderDetail")
	@ResponseBody
	public YgReturnOrderInfoModel returnorderDetail(String returnCode, Long userId) {

		return ygReturnOrderService.findReturnOrderInfo(returnCode, userId);
	}

	@RequestMapping("updateQuestionDesc")
	@ResponseBody
	public Message updateQuestionDesc(String desc, String returnCode, Long rodId) {
		AdminUser user = SessionUtil.getCurrentUser();
		YgReturnOrderDetail ygReturnOrderDetail = new YgReturnOrderDetail(rodId, desc);
		ygReturnOrderDetailService.update(ygReturnOrderDetail);
		ygReturnLogService.addReturnLog(returnCode, rodId, "更新明细处理方式", user.getTrueName(), "rodId=" + rodId + ";" + desc);
		return Message.success(null);
	}

	/**
	 * 退款标记
	 * 
	 * @param remark
	 * 
	 *            id:pid,refundPrice:realPrice,refundAccountPrice:realFundPrice,
	 *            remark:remark
	 * @return
	 * @throws YgException
	 */
	@RequestMapping("returnMoney")
	@ResponseBody
	public Message returnMoney(Long id, String remark, BigDecimal refundPrice, BigDecimal refundAccountPrice, PayType payType) throws YgException {
		AdminUser user = SessionUtil.getCurrentUser();
		return ygReturnOrderService.autoRefund(id, remark, user.getTrueName(), refundPrice, refundAccountPrice);

	}

	@RequestMapping("refundQuery")
	@ResponseBody
	public Message refund(String returnOrderCode) throws YgException {
		RefundRecord refund = ygWeChatService.refundQuery(returnOrderCode);
		// String str =
		// "<xml> <appid><![CDATA[wx563327e8dd35e422]]></appid>
		// <cash_fee><![CDATA[4100]]></cash_fee>
		// <mch_id><![CDATA[1320346801]]></mch_id>
		// <nonce_str><![CDATA[MascXmNceQmm2iCe]]></nonce_str>
		// <out_refund_no_0><![CDATA[R170504822580]]></out_refund_no_0>
		// <out_trade_no><![CDATA[170504161529]]></out_trade_no>
		// <refund_account_0><![CDATA[REFUND_SOURCE_UNSETTLED_FUNDS]]></refund_account_0>
		// <refund_channel_0><![CDATA[ORIGINAL]]></refund_channel_0>
		// <refund_count>1</refund_count> <refund_fee>4100</refund_fee>
		// <refund_fee_0>4100</refund_fee_0>
		// <refund_id_0><![CDATA[50000102812017050501043397321]]></refund_id_0>
		// <refund_recv_accout_0><![CDATA[北京银行储蓄卡9796]]></refund_recv_accout_0>
		// <refund_status_0><![CDATA[SUCCESS]]></refund_status_0>
		// <refund_success_time_0><![CDATA[2017-05-06
		// 15:07:26]]></refund_success_time_0>
		// <result_code><![CDATA[SUCCESS]]></result_code>
		// <return_code><![CDATA[SUCCESS]]></return_code>
		// <return_msg><![CDATA[OK]]></return_msg>
		// <sign><![CDATA[C5B1EBBF67E390B77B38E30E3655DD8C]]></sign>
		// <total_fee><![CDATA[4100]]></total_fee>
		// <transaction_id><![CDATA[4006452001201705049527762553]]></transaction_id>
		// </xml>";
		// RefundRecord refund = ListsuffixResultDeserializer.deserialize(str,
		// RefundRecord.class);
		return Message.success(refund);

	}

	/**
	 * 退换货入库标记
	 * 
	 * @param skuList
	 * @param remark
	 * @return
	 */
	@RequestMapping("returnOrderInstock")
	@ResponseBody
	public Message returnOrderInstock(String skuList, String remark) {
		List<YgReturnOrderDetail> stockInModels = JSON.parseObject(skuList, new TypeReference<List<YgReturnOrderDetail>>() {
		});
		return ygReturnOrderService.saveStockInOrder(stockInModels, getSession().getTrueName());
	}

	/**
	 * 审批单据
	 */
	@RequestMapping("auditReturnOrder")
	@ResponseBody
	public Message auditReturnOrder(String returnCode, Long userId, String remark, Boolean passOrderReject, OrderStatus orderStatus) {

		return ygReturnOrderService.auditReturnOrder(returnCode, remark, userId, getSession().getTrueName(), passOrderReject, orderStatus);
	}

	@RequestMapping("cancelReturn")
	@ResponseBody
	public Message cancelReturn(String returnCode, Long userId, String remark) {
		return ygReturnOrderService.cancelReturn(returnCode, remark, getSession().getTrueName());
	}

	@RequestMapping("getReturnLogs")
	@ResponseBody
	public List<YgReturnOrderLog> getReturnLogs(String returnCode) {
		return ygReturnOrderLogService.getReturnScheduleList(returnCode);

	}

	@RequestMapping("sendOrder")
	@ResponseBody
	public Message sendOrder(String returnCode, Long id, String expressCompany, String expressCode, String logisticsCode, int goodAmount) {
		return ygReturnOrderService.sendOutGoods(returnCode, expressCompany, logisticsCode, expressCode, Long.valueOf(goodAmount), getSession().getTrueName());

	}

	@RequestMapping("syncChanngeOrder")
	@ResponseBody
	public Message syncChanngeOrder(String returnCode) {

		YgReturnOrder returnOrder = ygReturnOrderService.findDetailByReCode(returnCode);
		WdtResult result = wdtService.createChangeOrder(returnOrder);
		if (result != null && result.getResultCode().equals(0)) {
			returnOrder.setWdtOrderCode(result.getErpOrderCode() + "");
			ygReturnOrderService.update(returnOrder);
		}
		return Message.success(result);

	}

	@RequestMapping("exportOrder")
	public void exportOrder(Date startDate, Date endDate, String returnType, String productName, HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		endDate = DateConvertUtils.addDay(endDate, 1);

		List<Map<String, Object>> list = ygReturnOrderService.getReturnOrderReport(startDate, endDate, returnType.equals("-1") ? null : returnType,
				productName);

		// InputStream
		// inputStream=OrderController.class.getClassLoader().getResourceAsStream("/template/orderlist.xls");//"template/orderlist.xls";
		byte[] bytes = fileService.downloadFromOss("template/returnorderlist.xlsx"); // ByteToInputStream.input2byte(inputStream);
		List<Map<String, Object>> dataMaps = new ArrayList<Map<String, Object>>();
		Map<String, Object> dataMap = new HashMap<String, Object>();

		dataMap.put("resultSet", list);
		dataMaps.add(dataMap);
		DocumentHandler.DownloadExcel(bytes, "退换货订单统计.xlsx", dataMap, request, response);
	}

	@RequestMapping("userSendOrder")
	@ResponseBody
	public Message userSendOrder(String returnCode, Long id, String userExpressCompany, String userExpressCode) {
		YgReturnOrder ygReturnOrder = ygReturnOrderService.findById(id);
		// YgReturnOrder ygReturnOrder=new YgReturnOrder();
		YgOrder order = ygOrderService.findByOrderId(ygReturnOrder.getOrderId());
		ygReturnOrder.setId(id);
		ygReturnOrder.setUserExpressCode(userExpressCode);
		ygReturnOrder.setUserExpressCompany(userExpressCompany);
		ygReturnOrder.setUpdateBy(getSession().getTrueName());
		ygReturnOrder.setUpdateTime(new Date());
		ygReturnOrder.setReturnStatus(ReturnStatus.WaitingInStock);
		ygReturnOrder.setReceiver(order.getReceiver());
		ygReturnOrder.setProvinceName(order.getProvinceName());
		ygReturnOrder.setCityName(order.getCityName());
		ygReturnOrder.setAreaName(order.getAreaName());
		ygReturnOrder.setAddress(order.getAddress());
		ygReturnOrder.setTelPhone(order.getTelPhone());
		ygReturnOrderService.update(ygReturnOrder);
		ygReturnOrderLogService.addReturnOrderLog(returnCode, "您的退货已寄回，等待入库。物流信息：" + ygReturnOrder.getUserExpressCompany() + ygReturnOrder.getUserExpressCode(),
				ReturnStatus.WaitingInStock, getSession().getTrueName(), null);
		return SUCCESS_MESSAGE;

	}

	@RequestMapping("getReturnOrderMoneryById")
	@ResponseBody
	public YgReturnOrder getReturnOrderMoneryById(Long id) {

		return ygReturnOrderService.findReturnOrderMoneryById(id);
	}

	@RequestMapping("pushChangeOrderBefore")
	@ResponseBody
	public Message pushChangeOrderBefore(String returnCode, Boolean isSend) throws WdtException {
		YgReturnOrder returnOrder = ygReturnOrderService.findDetailByReCode(returnCode);
		WdtQybResult result = wdtQybApi.pushChangeOrderBefore(returnOrder, isSend);
		return Message.success(result);

	}

	@RequestMapping("pushChangeOrderAfter")
	@ResponseBody
	public Message pushChangeOrderAfter(String returnCode) throws WdtException {
		YgReturnOrder returnOrder = ygReturnOrderService.findDetailByReCode(returnCode);
		WdtQybResult result = wdtQybApi.pushChangeOrderAfter(returnOrder);
		return Message.success(result);

	}

	@RequestMapping("alipayRefund")
	@ResponseBody
	public void alipayRefund(Long returnId, String transactionId, String returnCode, String batchNo, String paymentCode, Integer batchNum,
			BigDecimal refundPrice, BigDecimal refundAccountPrice, String remark, HttpServletRequest request, HttpServletResponse out)
			throws Exception {
		out.setHeader("Content-type", "text/html;charset=UTF-8");
		out.setCharacterEncoding("UTF-8");
		AdminUser adminUser = SessionUtil.getCurrentUser();
		// //////////////////////////////////请求参数//////////////////////////////////////

		// 批次号，必填，格式：当天日期[8位]+序列号[3至24位]，如：201603081000001

		// 退款笔数，必填，参数detail_data的值中，“#”字符出现的数量加1，最大支持1000笔（即“#”字符出现的数量999个）

		// 退款详细数据，必填，格式（支付宝交易号^退款金额^备注），多笔请用#隔开
		// String detail_data = new
		// String(request.getParameter("WIDdetail_data").getBytes("ISO-8859-1"),
		// "UTF-8");
		batchNum = 1;
		batchNo = ygFrameCodeService.getFrameCode(CodeType.BatchNo, new Date(), "yyyyMMdd", 6);


		/*
		 * 正常情况下定金订单，先退定金
		 */
		Message message = ygPrepayBookRecordService.refundRecordByReturnCode(returnCode, refundPrice);
		if (!Message.isSuccess(message)) {
			throw new Exception(message.getContent());
		}
		BigDecimal bookPrice = (BigDecimal) message.getExtra();
		refundPrice = refundPrice.subtract(bookPrice);

		YgAlipayRefundRecord record = new YgAlipayRefundRecord(batchNo, batchNum, transactionId, returnId, returnCode, refundPrice, refundAccountPrice, remark,
				adminUser.getTrueName());

		ygAlipayRefundRecordService.save(record);
		// ////////////////////////////////////////////////////////////////////////////////

		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", refundService);
		sParaTemp.put("partner", partner);
		sParaTemp.put("_input_charset", charset);
		sParaTemp.put("notify_url", refundFastpayNotifyUrl);
		sParaTemp.put("seller_user_id", sellerId);
		sParaTemp.put("refund_date", DateConvertUtils.formatDateTime(new Date()));
		sParaTemp.put("batch_no", batchNo);
		sParaTemp.put("batch_num", batchNum + "");
		sParaTemp.put("detail_data", transactionId + "^" + refundPrice + "^" + remark);

		sParaTemp = AlipaySubmit.buildRequestPara(sParaTemp);

		// 建立请求
		String buildRequest = AlipaySubmit.buildRequest(sParaTemp, "get", "确认");
		System.out.println("<html><body>" + buildRequest + "</body></html>");
		out.getWriter().println("<html><body>" + buildRequest + "</body></html>");
	}

	@RequestMapping(value = "refundFastpayNotifyUrl")
	public void refundFastpayNotifyUrl(HttpServletRequest request, HttpServletResponse out) throws IOException {
		Map<String, String> params = this.getAlipayNotifyParam(request);

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 批次号

		String batchNo = new String(request.getParameter("batch_no").getBytes("ISO-8859-1"), "UTF-8");

		// 批量退款数据中转账成功的笔数

		String success_num = new String(request.getParameter("success_num").getBytes("ISO-8859-1"), "UTF-8");

		// 批量退款数据中的详细信息
		String result_details = new String(request.getParameter("result_details").getBytes("ISO-8859-1"), "UTF-8");

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

		if (AlipayNotify.verify(params)) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			// 请在这里加上商户的业务逻辑程序代码
			threadPool.getExecutorService().execute(new Runnable() {

				@Override
				public void run() {
					ygReturnOrderService.alipayRefundSuccess(batchNo, success_num, result_details);

				}
			});
			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

			// 判断是否在商户网站中已经做过了这次通知返回的处理
			// 如果没有做过处理，那么执行商户的业务程序
			// 如果有做过处理，那么不执行商户的业务程序

			out.getWriter().print("success"); // 请不要修改或删除

			// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

			// ////////////////////////////////////////////////////////////////////////////////////////
		} else {// 验证失败
			out.getWriter().print("fail");
		}

	}

	private Map<String, String> getAlipayNotifyParam(HttpServletRequest request) {
		Map<String, String> params = new HashMap<String, String>();
		Map<?, ?> requestParams = request.getParameterMap();
		for (Iterator<?> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
			 */
			params.put(name, valueStr);
		}
		return params;
	}

	@RequestMapping("exportInstockDetail")
	public void exportInstockDetail(Date startDate, Date endDate, String returnType, String[] questionDesc, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		if (StringUtil.isNotBlank(returnType) && "-1".equals(returnType)) {
			returnType = null;
		}
		List<Map<String, Object>> list = ygReturnOrderDetailService.getReturnInStockDetail(returnType, startDate, endDate, questionDesc);

		byte[] bytes = fileService.downloadFromOss("template/exportInstockDetail.xls"); //
		// byte[] bytes =
		// FileUtil.getBytes("C:/Users/admin/Desktop/上线/exportInstockDetail.xls");
		List<Map<String, Object>> dataMaps = new ArrayList<Map<String, Object>>();
		Map<String, Object> dataMap = new HashMap<String, Object>();

		dataMap.put("resultSet", list);
		dataMaps.add(dataMap);
		DocumentHandler.DownloadExcel(bytes, "退换入库明细.xls", dataMap, request, response);
	}

	/**
	 * 退换货率
	 * @param reportReq
	 * @return
	 */
	@RequestMapping("returnOrderReport")
	@ResponseBody
	public Map<String, Object> returnOrderReport(ReturnOrderReportReq reportReq) {
		reportReq.initDate();
		List<ReturnOrderReportModel> result = ygReturnOrderReportService.findList(reportReq);
		ResultSet<ReturnOrderReportModel> resultSet = new ResultSet<>(1L, result);
		return resultSet.toDatatables(null);
	}

	/**
	 * 导出退换货率
	 * @param reportReq
	 */
	@RequestMapping("exportReturnOrderReport")
	public void exportReturnOrderReport(ReturnOrderReportReq reportReq, HttpServletRequest request,
										HttpServletResponse response) {
		reportReq.initDate();
		List<ReturnOrderReportModel> result = ygReturnOrderReportService.findList(reportReq);
		byte[] bytes = fileService.downloadFromOss("template/return_order_report.xlsx");
		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put("resultSet", result);
		DocumentHandler.DownloadExcel(bytes, "退换货率.xls", dataMap, request, response);
	}
}
